<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <meta name="author" content="隐星魂 (Roy.Sun)">
        
        <link rel="shortcut icon" href="../../img/favicon.ico">
        <title>7.线程 - 玄武操作系统</title>
        <link href="../../css/bootstrap.min.css" rel="stylesheet">
        <link href="../../css/font-awesome.min.css" rel="stylesheet">
        <link href="../../css/base.css" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.3/styles/color-brewer.min.css">

        <script src="../../js/jquery-1.10.2.min.js" defer></script>
        <script src="../../js/bootstrap.min.js" defer></script>
        <script src="https://cdn.staticfile.org/highlight.js/10.0.3/highlight.min.js"></script>
        <script>hljs.initHighlightingOnLoad();</script> 
    </head>

    <body>
        <div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
            <div class="container">
                <a class="navbar-brand" href="../..">玄武操作系统</a>
                <!-- Expander button -->
                <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <!-- Expanded navigation -->
                <div id="navbar-collapse" class="navbar-collapse collapse">
                        <!-- Main navigation -->
                        <ul class="nav navbar-nav">
                            <li class="navitem">
                                <a href="../.." class="nav-link">主页</a>
                            </li>
                            <li class="navitem">
                                <a href="../../License/" class="nav-link">开源协议</a>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">快速开发指南 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">STM32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/stm32/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/02-atkh743/" class="dropdown-item">02-正点原子阿波罗H743开发板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/03-fk429m/" class="dropdown-item">03-反客F429核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/04-atkf103core/" class="dropdown-item">04-正点原子F103核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/05-atkf407core/" class="dropdown-item">05-正点原子F407核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/06-WeActH750/" class="dropdown-item">06-微行电子H750开发板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/07-Project-From-Scratch-Guide/" class="dropdown-item">07-自定义工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">GD32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/gd32/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/gd32/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">GD32V</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/gd32v/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/gd32v/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">NXP S32K</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/s32k/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/s32k/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">玄武内核模块</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/xwko/01-XuanWuKO-Guide/" class="dropdown-item">01-上手指南</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown active">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">应用手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../00-Index/" class="dropdown-item">0.目录</a>
</li>
                                    
<li>
    <a href="../01-Brief/" class="dropdown-item">1.简介</a>
</li>
                                    
<li>
    <a href="../02-Basic-System-Architecture/" class="dropdown-item">2.系统基本架构</a>
</li>
                                    
<li>
    <a href="../03-Build-System/" class="dropdown-item">3.构建系统</a>
</li>
                                    
<li>
    <a href="../04-Boot-Flow/" class="dropdown-item">4.启动流程</a>
</li>
                                    
<li>
    <a href="../05-IRQ/" class="dropdown-item">5.中断控制</a>
</li>
                                    
<li>
    <a href="../06-SKD/" class="dropdown-item">6.调度器</a>
</li>
                                    
<li>
    <a href="./" class="dropdown-item active">7.线程</a>
</li>
                                    
<li>
    <a href="../08-SWT/" class="dropdown-item">8.软件定时器</a>
</li>
                                    
<li>
    <a href="../09-PM/" class="dropdown-item">9.电源管理</a>
</li>
                                    
<li>
    <a href="../10-Lock/" class="dropdown-item">10.锁</a>
</li>
                                    
<li>
    <a href="../11-Sync/" class="dropdown-item">11.同步</a>
</li>
                                    
<li>
    <a href="../12-MM/" class="dropdown-item">12.内存管理</a>
</li>
                                    
<li>
    <a href="../13-C-Lib/" class="dropdown-item">13.玄武C库</a>
</li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">Lua手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../LuaManual/00-Index/" class="dropdown-item">0.目录</a>
</li>
                                    
<li>
    <a href="../../LuaManual/01-Brief/" class="dropdown-item">1.简介</a>
</li>
                                    
<li>
    <a href="../../LuaManual/02-XWXT/" class="dropdown-item">2.全局导出表</a>
</li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">3.XWOS内核</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/03-XWOS/01-SDK/" class="dropdown-item">3.1.线程库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/02-Spinlock/" class="dropdown-item">3.2.自旋锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/03-Seqlock/" class="dropdown-item">3.3.顺序锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/04-Mutex/" class="dropdown-item">3.4.互斥锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/05-Semaphore/" class="dropdown-item">3.5.信号量库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/06-Condition/" class="dropdown-item">3.6.条件量库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/07-Flag/" class="dropdown-item">3.7.事件标志库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/08-Barrier/" class="dropdown-item">3.8.线程栅栏库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/09-Selector/" class="dropdown-item">3.9.信号选择器库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/10-PM/" class="dropdown-item">3.10.电源管理</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">4.玄武Lua函数库</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/04-XWLIB/01-Bitmap/" class="dropdown-item">4.1.位图</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">5.设备栈</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/05-XWDS/01-Soc/" class="dropdown-item">5.1.SOC</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/02-GPIO/" class="dropdown-item">5.2.GPIO</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/03-UART/" class="dropdown-item">5.3.UART</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/04-SPI-Master/" class="dropdown-item">5.4.SPI Master</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/05-IIC-Master/" class="dropdown-item">5.5.IIC Master</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">移植笔记 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../PortingNote/00-Index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../PortingNote/01-Porting-Note/" class="dropdown-item">移植笔记</a>
</li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">ARM-Cortex-M</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../PortingNote/02-ARM-Cortex-M/01-ARM-Cortex-M-Porting-Note/" class="dropdown-item">架构移植笔记</a>
</li>
            
<li>
    <a href="../../PortingNote/02-ARM-Cortex-M/02-STM32-Porting-Note/" class="dropdown-item">STM32</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">RISC-V</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../PortingNote/03-RISC-V/01-GD32V-Porting-Note/" class="dropdown-item">GD32V</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">规范 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../Specification/00-Index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../Specification/01-Git-Commit-Specification/" class="dropdown-item">git-commit规范</a>
</li>
                                    
<li>
    <a href="../../Specification/02-Version-Branch-Specification/" class="dropdown-item">版本分支规范</a>
</li>
                                </ul>
                            </li>
                        </ul>

                    <ul class="nav navbar-nav ml-auto">
                        <li class="nav-item">
                            <a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
                                <i class="fa fa-search"></i> 搜索
                            </a>
                        </li>
                            <li class="nav-item">
                                <a rel="prev" href="../06-SKD/" class="nav-link">
                                    <i class="fa fa-arrow-left"></i> 上一篇
                                </a>
                            </li>
                            <li class="nav-item">
                                <a rel="next" href="../08-SWT/" class="nav-link">
                                    下一篇 <i class="fa fa-arrow-right"></i>
                                </a>
                            </li>
                    </ul>
                </div>
            </div>
        </div>

        <div class="container">
            <div class="row">
                    <div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
    <div class="navbar-header">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
            <span class="fa fa-angle-down"></span>
        </button>
    </div>

    
    <div id="toc-collapse" class="navbar-collapse collapse card bg-secondary">
        <ul class="nav flex-column">
            
            <li class="nav-item" data-level="1"><a href="#7" class="nav-link">7.线程</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#71" class="nav-link">7.1.描述</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#72" class="nav-link">7.2.线程的创建、初始化与删除、销毁</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#73" class="nav-link">7.3.线程的睡眠</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#74" class="nav-link">7.4.线程的退出与返回值</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#75" class="nav-link">7.5.线程的冻结与解冻</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#76" class="nav-link">7.6.线程的迁移</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#77" class="nav-link">7.7.配置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#78api" class="nav-link">7.8.API参考</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#79" class="nav-link">7.9.附录</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
        </ul>
    </div>
</div></div>
                    <div class="col-md-9" role="main">

<h1 id="7">7.线程</h1>
<h2 id="71">7.1.描述</h2>
<p>线程是操作系统最基本的调度单位，在其他RTOS中可能称之为<strong>任务</strong>。玄武OS的线程，
除了最基本的运行、睡眠、退出操作外，还支持冻结与解冻，迁移等操作。</p>
<h3 id="_1">线程的状态</h3>
<p><img alt="img" src="../res/figure/thread-state.png" title="玄武OS线程状态图" /></p>
<ul>
<li><strong>待命（standby）</strong> ：线程已被初始化，但未指定主函数。</li>
<li><strong>就绪（ready）</strong> ：线程已加入到就绪队列中。</li>
<li><strong>运行（running）</strong> ：线程正在运行，每个CPU中只可能存在一个线程正在运行。</li>
<li><strong>睡眠（sleeping）</strong> ：线程正在睡眠。</li>
<li><strong>阻塞（blocking）</strong> ：线程正在等待，可与 <strong>睡眠</strong> 态组合。</li>
<li><strong>冻结（frozen）</strong> ：线程已被冻结。</li>
<li><strong>退出（exiting）</strong> ：线程即将结束。</li>
<li><strong>迁移（migrating）</strong> ：线程正处于迁移到别的CPU的过程中。</li>
</ul>
<hr />
<h2 id="72">7.2.线程的创建、初始化与删除、销毁</h2>
<p>玄武OS内核提供静态初始化和动态创建两种方式建立线程：</p>
<ul>
<li>静态初始化与销毁<ul>
<li>初始化：<code>xwos_thrd_init()</code>；</li>
<li>销毁：<code>xwos_thrd_destroy()</code>；</li>
<li><strong>静态</strong>是指用户预先定义对象，这些对象在编译时由编译器分配内存；</li>
<li>静态初始化线程还需预先定义栈数组，作用域应该为全局。
    栈数组的首地址与大小，必须要满足CPU的ABI规则，例如ARM，就要求8字节对齐，
    因此在定义栈数组时需要使用<code>__xwcc__aligned(8)</code>来修饰，且大小是8的倍数。</li>
</ul>
</li>
<li>动态创建与删除<ul>
<li>创建：<code>xwos_thrd_create()</code>；</li>
<li>删除：<code>xwos_thrd_delete()</code>；</li>
<li><strong>动态</strong>是指程序在运行时，通过内存分配函数从某个内存区域上申请分配一块内存，
    并把这块内存初始化为所需要的对象。使用完毕后，需要通过删除来释放内存；</li>
<li><strong>动态</strong>方式创建的线程，其栈内存地址对齐问题由操作系统内核处理。</li>
</ul>
</li>
</ul>
<h3 id="_2">线程属性</h3>
<p>线程在创建时，可通过参数<code>attr</code>设定其属性，取值：</p>
<ul>
<li><code>XWOS_SKDATTR_PRIVILEGED</code>：表示线程拥有系统特权，<ul>
<li>CPU的一些寄存器需要开启特权后才可访问，例如全局中断的开关：<ul>
<li>在ARMv6m/ARMv7m中，是通过<strong>CONTROL</strong>寄存器的bit0(nPRIV)来实现的；</li>
<li>在Embedded PowerPC中，是通过<strong>MSR</strong>寄存器的bit17(PR)来实现的。</li>
</ul>
</li>
</ul>
</li>
<li><code>XWOS_SKDATTR_DETACHED</code>：表示线程是分离的<ul>
<li>类似于POSIX线程的detached属性，DETACHED的线程退出后，系统自动回收其资源。</li>
</ul>
</li>
<li><code>XWOS_SKDATTR_JOINABLE</code>：表示线程是可连接的，此为默认属性<ul>
<li>类似于POSIX线程的joinable属性，JOINABLE的线程退出后，父线程必须
    调用<code>xwos_thrd_stop()</code>或<code>xwos_thrd_join()</code>回收其资源。</li>
</ul>
</li>
</ul>
<h3 id="_3">示例</h3>
<ul>
<li>应用模块：<code>xwam/example/thread/create</code></li>
<li>用法：<ul>
<li>在配置文件<code>xwbd/电路板名称/cfg/xwam.h</code>中
    定义宏<code>XWAMCFG_example_thread_create</code>为<code>1</code>；</li>
<li>在初始化流程中（例如：<code>xwos_main()</code>）调
    用<code>example_thread_create_start()</code>启动模块。</li>
</ul>
</li>
</ul>
<hr />
<h2 id="73">7.3.线程的睡眠</h2>
<p>线程睡眠常用来做精度要求不高的延迟，玄武OS内核提供两种睡眠方式：</p>
<ul>
<li>睡眠超时的时间是以当前系统tick时间作为初始值进行计算的。
    这种方式使用简单，只需提供需要睡眠的tick时间即可，但精度略低一些。<ul>
<li>API：<code>xwos_cthrd_sleep()</code></li>
</ul>
</li>
<li>睡眠的时间起点由调用者提供，这种方式通常用来做精确的周期性延迟。
    第一次调用时，需要提供一个时间原点和周期增量，然后这个函数每次返回时
    都会在时间原点上增加一次周期增量，以便作为下一次调用的时间原点，由此循环可形成
    精准的周期性延迟。<ul>
<li>API：<code>xwos_cthrd_sleep_from()</code></li>
</ul>
</li>
</ul>
<h3 id="_4">示例</h3>
<ul>
<li>应用模块：<code>xwam/example/thread/sleep</code></li>
<li>用法：<ul>
<li>在配置文件<code>xwbd/电路板名称/cfg/xwam.h</code>中
    定义宏<code>XWAMCFG_example_thread_sleep</code>为<code>1</code>；</li>
<li>在初始化流程中（例如：<code>xwos_main()</code>）调
    用<code>example_thread_sleep_start()</code>启动模块。</li>
</ul>
</li>
</ul>
<hr />
<h2 id="74">7.4.线程的退出与返回值</h2>
<h3 id="741">7.4.1.线程的退出</h3>
<p>线程退出通常有两种方式：</p>
<ul>
<li>主函数直接<code>return</code></li>
</ul>
<pre><code class="C">xwer_t foo_task_thrd(void * arg)
{
        /* 省略 ... */
        return rc;
}
</code></pre>

<ul>
<li>主函数中调用<code>xwos_cthrd_exit()</code></li>
</ul>
<p>此API的用法类似于POSIX中的函数<code>pthread_exit()</code>，调用的线程会立即终止并抛出返回值。</p>
<pre><code class="C">xwer_t foo_task_thrd(void *arg)
{
        xwer_t rc;
        /* 省略 ... */
        xwos_cthrd_exit(rc); /* 线程在此处结束，并抛出返回值rc */
        /* 后面的代码不再执行 ... */
}
</code></pre>

<h3 id="742">7.4.2.线程的退出的方式</h3>
<p>玄武OS的线程类似于pthread，分为Detached属性与Joinable属性，可在创建线程时的<code>attr</code>参
数中指明属性：</p>
<ul>
<li><code>XWOS_SKDATTR_DETACHED</code>：线程是分离的</li>
<li><code>XWOS_SKDATTR_JOINABLE</code>：线程是可连接的，默认属性</li>
</ul>
<h5 id="xwos_skdattr_joinable"><code>XWOS_SKDATTR_JOINABLE</code>的线程</h5>
<ul>
<li>类似于POSIX线程的Joinable属性，JOINABLE的线程退出后，父线程必须
    调用<code>xwos_thrd_stop()</code>或<code>xwos_thrd_join()</code>回收其资源；</li>
<li>父线程可通过<code>xwos_thrd_stop()</code>或<code>xwos_thrd_join()</code>获取子线程退出时
    的返回值；</li>
<li>函数<code>xwos_thrd_stop()</code>或<code>xwos_thrd_join()</code>会阻塞调用的线程，直到子线程退出；</li>
<li>函数<code>xwos_thrd_cancel()</code>只通知子线程退出，不会等待；</li>
<li>函数<code>xwos_thrd_join()</code>只会等待子线程退出，不会通知子线程退出；</li>
<li>函数<code>xwos_thrd_stop()</code>会先通知子线程退出，再等待子线程退出，相当
    于<code>xwos_thrd_cancel()</code>+<code>xwos_thrd_join()</code>；</li>
</ul>
<h5 id="xwos_skdattr_detached"><code>XWOS_SKDATTR_DETACHED</code>的线程</h5>
<ul>
<li>类似于POSIX线程的detached属性，DETACHED的线程退出后，系统自动回收其资源。</li>
<li>不可对DETACHED的线程使用<code>xwos_thrd_join()</code>和<code>xwos_thrd_stop()</code>，
    但可使用<code>xwos_thrd_cancel()</code>通知其退出。</li>
</ul>
<h3 id="743">7.4.3.线程的退出通知</h3>
<ul>
<li>子线程收到退出通知后，只会中断阻塞态和睡眠态，并不会被“暗杀”；</li>
<li>子线程可通过<code>xwos_cthrd_shld_stop()</code>获取是否收到了退出通知；</li>
<li>子线程收到退出通知后，可以选择忽略，也可选择清理资源后退出；</li>
<li>子线程可将是否收到退出通知作为主循环的条件：</li>
</ul>
<pre><code class="C">xwer_t thread_main(void * arg)
{
        xwer_t rc = XWOK;

        while (!xwos_cthrd_shld_stop()) {
                thread loop ...;
        }
        return rc;
}
</code></pre>

<ul>
<li><code>xwos_cthrd_shld_stop()</code>还有一个扩展API：<code>xwos_cthrd_frz_shld_stop()</code>，
    此函数集成了线程的冻结点。</li>
</ul>
<h3 id="744">7.4.4.示例</h3>
<ul>
<li>应用模块：<code>xwam/example/thread/exit</code></li>
<li>用法：<ul>
<li>在配置文件<code>xwbd/电路板名称/cfg/xwam.h</code>中
    定义宏<code>XWAMCFG_example_thread_exit</code>为<code>1</code>；</li>
<li>在初始化流程中（例如：<code>xwos_main()</code>）调
    用<code>example_thread_exit_start()</code>启动模块。</li>
</ul>
</li>
</ul>
<hr />
<h2 id="75">7.5.线程的冻结与解冻</h2>
<h3 id="751">7.5.1.冻结</h3>
<p>线程的冻结操作，是用来支持内核的一些特殊功能的。用户不能随意冻结线程。
在以下情况，玄武OS内核要求线程进入冻结状态：</p>
<ul>
<li>系统准备进入低功耗模式。如果此时线程还在运行，很有可能因其正在访问硬件资源、
    占用锁，导致系统关闭硬件、清理资源时发生异常。因此线程需要运行到一个
    特殊的点后冻结，这个点称为<strong>冻结点</strong>。线程进入冻结点时，需要返回到最外层的
    主函数中，并释放掉所有的锁和硬件资源。</li>
<li>线程迁移至另一个CPU。线程迁移时，也需要返回至最外层的冻结点，保证不能占用当前
    CPU的任何资源。</li>
</ul>
<h3 id="752">7.5.2.解冻</h3>
<p>线程的解冻一般不由用户来操作，系统完成特殊功能后会自动对线程进行解冻：</p>
<ul>
<li>系统退出低功耗模式时；</li>
<li>线程迁移操作已经完成。</li>
</ul>
<h3 id="753">7.5.3.线程冻结的示例</h3>
<p>玄武OS的线程被要求进入冻结时，会中断阻塞态或睡眠态，这些函数会返回
错误码-EINTR或-ERESTARTSYS。然后线程可在此时释放掉占用的锁和资源，再执行到
主函数的冻结点进行冻结。</p>
<pre><code class="C">xwer_t foo_task_thread(void *arg)
{
        xwer_t rc;
        bool was_frz;

        /* 初始化... */

        /* 冻结点在函数xwos_cthrd_frz_shld_stop()内部：
           + 此函数会判读当前线程是否需要冻结，若是，在函数内部冻结线程。
           + 此函数同时还判断线程是否需要退出，若是，返回false。
           + 此函数的参数用来告诉用户刚才线程是否被冻结过，若是，was_frz
             被置为true，否则为false。
        */
        while (!xwos_cthrd_frz_shld_stop(&amp;was_frz)) {
                rc = fsm(); /* 状态机 */
        }
        /* 省略 ... */
        return rc;
}
</code></pre>

<p>上面的例子比较简单，在不需要释放锁和资源的场合使用。如果线程冻结前需要
做一些清理操作，可以这样来写主函数中的循环：</p>
<pre><code class="C">xwer_t foo_task_thread(void *arg)
{
        xwer_t rc;

        /* 初始化... */

        /* 线程循环 */
        /* xwos_cthrd_shld_stop()只判断线程是否需要退出 */
        while (!xwos_cthrd_shld_stop()) {
                rc = fsm(...); /* 在状态机中阻塞在某个同步对象或锁上 */
                if ((-EINTR == rc) || (-ERESTARTSYS == rc)) {
                        /* 线程的阻塞态或睡眠态被中断时，会收到
                           错误码-EINTR或-ERESTARTSYS，进一步判断是否被
                           系统要求冻结。 */
                        if (xwos_cthrd_shld_frz()) { /* 判断是否需要冻结 */
                                free_resource(); /* 释放锁和资源... */

                                xwos_cthrd_freeze(); /* 冻结点 */
                                /* 冻结后，系统可能发生低功耗操作，也可能迁移此线程 */
                                /* 线程解冻后，代码回到这里，如果对线程进行了迁移，
                                   另一个CPU从此处开始运行此线程。 */

                                alloc_resource(); /* 重新请求资源和锁... */
                        } else {
                                /* 处理其他原因导致的中断，例如终止请求。 */
                        }
                }
        }

        /* 省略 ... */
        return rc;
}
</code></pre>

<hr />
<h2 id="76">7.6.线程的迁移</h2>
<p>在多核系统中，玄武OS的线程只会在某个CPU上被调度，玄武OS内核并不会自动对线程做均衡处理。
线程会和CPU存在绑定关系。如果需要改变这种绑定关系（例如引入用户自己的线程均衡服务），
需要对线程进行迁移，可以使用API：<code>xwos_thrd_migrate()</code>。</p>
<h3 id="_5">迁移流程</h3>
<ul>
<li>假定条件：线程正在CPU-A上，准备迁移到CPU-B上</li>
<li>流程：<ul>
<li>用户在任意CPU的任意上下文调用API：<code>xwos_thrd_migrate()</code>；<ul>
<li>系统向CPU-A发送调度器服务中断，提出“<strong>迁移出</strong>”的申请；</li>
<li>CPU-A切换至调度器服务中断，向线程设置冻结标志，并中断线程的阻塞态和睡眠态，
    然后退出中断上下文；</li>
<li>CPU-A中线程被重新调度，并运行到冻结点；</li>
<li>线程在冻结点向CPU-A发送调度器服务中断，执行<strong>冻结</strong>操作；</li>
<li>线程冻结后，CPU-A向CPU-B申请调度器服务中断，提出“<strong>迁移进</strong>”的申请；</li>
<li>CPU-B切换至调度器服务中断，把线程加入到自己的调度器中，解除线程的冻结状态，
    并加入就绪列表中；</li>
<li>迁移完成，线程开始在CPU-B中调度。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="77">7.7.配置</h2>
<h5 id="cfgxwosh">cfg/xwos.h</h5>
<ul>
<li>MP内核配置：<ul>
<li>调度器<ul>
<li><code>XWMPCFG_SKD_PRIORITY_RT_NUM</code>：调度器实时优先级数量；</li>
<li><code>XWMPCFG_SKD_TCB_MEMSLICE</code>：是否启用TCB对象缓存；</li>
</ul>
</li>
</ul>
</li>
<li>UP内核配置：<ul>
<li>调度器<ul>
<li><code>XWUPCFG_SKD_PRIORITY_RT_NUM</code>：调度器实时优先级数量；</li>
<li><code>XWUPCFG_SKD_THRD_EXIT</code>：是否启用线程退出，取值：1|0；</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="78api">7.8.API参考</h2>
<ul>
<li>头文件：<code>xwos/osal/skd.h</code></li>
<li>注释：见头文件</li>
</ul>
<h2 id="79">7.9.附录</h2>
<ul>
<li><a href="../00-Index/">返回目录</a></li>
</ul></div>
            </div>
        </div>

        <footer class="col-md-12">
            <hr>
            <p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
        </footer>
        <script>
            var base_url = "../..",
                shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
        </script>
        <script src="../../js/base.js" defer></script>
        <script src="../../search/main.js" defer></script>

        <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="searchModalLabel">搜索</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
                <p>
                    在这里所有文档：
                </p>
                <form>
                    <div class="form-group">
                        <input type="search" class="form-control" placeholder="搜索..." id="mkdocs-search-query" title="Type search term here">
                    </div>
                </form>
                <div id="mkdocs-search-results"></div>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
              <table class="table">
                <thead>
                  <tr>
                    <th style="width: 20%;">Keys</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="help shortcut"><kbd>?</kbd></td>
                    <td>Open this help</td>
                  </tr>
                  <tr>
                    <td class="next shortcut"><kbd>n</kbd></td>
                    <td>Next page</td>
                  </tr>
                  <tr>
                    <td class="prev shortcut"><kbd>p</kbd></td>
                    <td>Previous page</td>
                  </tr>
                  <tr>
                    <td class="search shortcut"><kbd>s</kbd></td>
                    <td>Search</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div>

    </body>
</html>
